--- /dev/null
+use glib::translate::{Stash, ToGlib, ToGlibPtr};
+use ostree_sys::OstreeRepoCheckoutAtOptions;
+use std::os::raw::c_char;
+use std::path::PathBuf;
+use {RepoCheckoutMode, RepoCheckoutOverwriteMode};
+use {RepoDevInoCache, SePolicy};
+
+#[derive(PartialEq, Eq, Hash, Debug, Clone)]
+pub struct RepoCheckoutAtOptions {
+ pub mode: RepoCheckoutMode,
+ pub overwrite_mode: RepoCheckoutOverwriteMode,
+ pub enable_uncompressed_cache: bool,
+ pub enable_fsync: bool,
+ pub process_whiteouts: bool,
+ pub no_copy_fallback: bool,
+ pub force_copy: bool,
+ pub bareuseronly_dirs: bool,
+ pub force_copy_zerosized: bool,
+ pub subpath: Option<PathBuf>,
+ pub devino_to_csum_cache: Option<RepoDevInoCache>,
+ // pub filter: OstreeRepoCheckoutFilter,
+ // pub filter_user_data: gpointer,
+ pub sepolicy: Option<SePolicy>,
+ pub sepolicy_prefix: Option<String>,
+}
+
+impl Default for RepoCheckoutAtOptions {
+ fn default() -> Self {
+ RepoCheckoutAtOptions {
+ mode: RepoCheckoutMode::None,
+ overwrite_mode: RepoCheckoutOverwriteMode::None,
+ enable_uncompressed_cache: false,
+ enable_fsync: false,
+ process_whiteouts: false,
+ no_copy_fallback: false,
+ force_copy: false,
+ bareuseronly_dirs: false,
+ force_copy_zerosized: false,
+ subpath: None,
+ devino_to_csum_cache: None,
+ sepolicy: None,
+ sepolicy_prefix: None,
+ }
+ }
+}
+
+impl<'a> ToGlibPtr<'a, *const OstreeRepoCheckoutAtOptions> for RepoCheckoutAtOptions {
+ type Storage = (
+ Box<OstreeRepoCheckoutAtOptions>,
+ Stash<'a, *const c_char, Option<PathBuf>>,
+ Stash<'a, *const c_char, Option<String>>,
+ );
+
+ fn to_glib_none(&'a self) -> Stash<*const OstreeRepoCheckoutAtOptions, Self> {
+ let mut options = Box::new(unsafe { std::mem::zeroed::<OstreeRepoCheckoutAtOptions>() });
+ options.mode = self.mode.to_glib();
+ options.overwrite_mode = self.overwrite_mode.to_glib();
+ options.enable_uncompressed_cache = self.enable_uncompressed_cache.to_glib();
+ options.enable_fsync = self.enable_fsync.to_glib();
+ options.process_whiteouts = self.process_whiteouts.to_glib();
+ options.no_copy_fallback = self.no_copy_fallback.to_glib();
+ options.force_copy = self.force_copy.to_glib();
+ options.bareuseronly_dirs = self.bareuseronly_dirs.to_glib();
+ options.force_copy_zerosized = self.force_copy_zerosized.to_glib();
+ let subpath = self.subpath.to_glib_none();
+ options.subpath = subpath.0;
+ let sepolicy_prefix = self.sepolicy_prefix.to_glib_none();
+ options.sepolicy_prefix = sepolicy_prefix.0;
+
+ /*
+ devino_to_csum_cache: None,
+ sepolicy: None,
+ */
+
+ Stash(options.as_ref(), (options, subpath, sepolicy_prefix))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use gio::{File, NONE_CANCELLABLE};
+ use glib_sys::{GFALSE, GTRUE};
+ use ostree_sys::{
+ OSTREE_REPO_CHECKOUT_MODE_NONE, OSTREE_REPO_CHECKOUT_MODE_USER,
+ OSTREE_REPO_CHECKOUT_OVERWRITE_NONE, OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL,
+ };
+ use std::ffi::{CStr, CString};
+ use std::ptr;
+
+ #[test]
+ fn should_convert_default_options() {
+ let options = RepoCheckoutAtOptions::default();
+ let stash = options.to_glib_none();
+ let ptr = stash.0;
+ unsafe {
+ assert_eq!((*ptr).mode, OSTREE_REPO_CHECKOUT_MODE_NONE);
+ assert_eq!((*ptr).overwrite_mode, OSTREE_REPO_CHECKOUT_OVERWRITE_NONE);
+ assert_eq!((*ptr).enable_uncompressed_cache, GFALSE);
+ assert_eq!((*ptr).enable_fsync, GFALSE);
+ assert_eq!((*ptr).process_whiteouts, GFALSE);
+ assert_eq!((*ptr).no_copy_fallback, GFALSE);
+ assert_eq!((*ptr).force_copy, GFALSE);
+ assert_eq!((*ptr).bareuseronly_dirs, GFALSE);
+ assert_eq!((*ptr).force_copy_zerosized, GFALSE);
+ assert_eq!((*ptr).unused_bools, [GFALSE; 4]);
+ assert_eq!((*ptr).subpath, ptr::null());
+ assert_eq!((*ptr).devino_to_csum_cache, ptr::null_mut());
+ assert_eq!((*ptr).unused_ints, [0; 6]);
+ assert_eq!((*ptr).unused_ptrs, [ptr::null_mut(); 3]);
+ assert_eq!((*ptr).filter, None);
+ assert_eq!((*ptr).filter_user_data, ptr::null_mut());
+ assert_eq!((*ptr).sepolicy, ptr::null_mut());
+ assert_eq!((*ptr).sepolicy_prefix, ptr::null());
+ }
+ }
+
+ #[test]
+ fn should_convert_non_default_options() {
+ let options = RepoCheckoutAtOptions {
+ mode: RepoCheckoutMode::User,
+ overwrite_mode: RepoCheckoutOverwriteMode::UnionIdentical,
+ enable_uncompressed_cache: true,
+ enable_fsync: true,
+ process_whiteouts: true,
+ no_copy_fallback: true,
+ force_copy: true,
+ bareuseronly_dirs: true,
+ force_copy_zerosized: true,
+ subpath: Some("sub/path".into()),
+ devino_to_csum_cache: Some(RepoDevInoCache::new()),
+ sepolicy: Some(SePolicy::new(&File::new_for_path("a/b"), NONE_CANCELLABLE).unwrap()),
+ sepolicy_prefix: Some("prefix".into()),
+ };
+ let stash = options.to_glib_none();
+ let ptr = stash.0;
+ unsafe {
+ assert_eq!((*ptr).mode, OSTREE_REPO_CHECKOUT_MODE_USER);
+ assert_eq!(
+ (*ptr).overwrite_mode,
+ OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL
+ );
+ assert_eq!((*ptr).enable_uncompressed_cache, GTRUE);
+ assert_eq!((*ptr).enable_fsync, GTRUE);
+ assert_eq!((*ptr).process_whiteouts, GTRUE);
+ assert_eq!((*ptr).no_copy_fallback, GTRUE);
+ assert_eq!((*ptr).force_copy, GTRUE);
+ assert_eq!((*ptr).bareuseronly_dirs, GTRUE);
+ assert_eq!((*ptr).force_copy_zerosized, GTRUE);
+ assert_eq!((*ptr).unused_bools, [GFALSE; 4]);
+ assert_eq!(
+ CStr::from_ptr((*ptr).subpath),
+ CString::new("sub/path").unwrap().as_c_str()
+ );
+ assert_ne!((*ptr).devino_to_csum_cache, ptr::null_mut());
+ assert_eq!((*ptr).unused_ints, [0; 6]);
+ assert_eq!((*ptr).unused_ptrs, [ptr::null_mut(); 3]);
+ assert_eq!((*ptr).filter, None);
+ assert_eq!((*ptr).filter_user_data, ptr::null_mut());
+ assert_ne!((*ptr).sepolicy, ptr::null_mut());
+ assert_eq!(
+ CStr::from_ptr((*ptr).sepolicy_prefix),
+ CString::new("prefix").unwrap().as_c_str()
+ );
+ }
+ }
+}
extern crate gio;
extern crate glib;
+extern crate openat;
extern crate ostree;
extern crate tempfile;
#[macro_use]
use gio::prelude::*;
use gio::NONE_CANCELLABLE;
use glib::prelude::*;
-use ostree::{ObjectName, ObjectType};
+use ostree::{
+ ObjectName, ObjectType, RepoCheckoutAtOptions, RepoCheckoutMode, RepoCheckoutOverwriteMode,
+};
+use std::os::unix::io::AsRawFd;
#[test]
fn should_commit_content_to_repo_and_list_refs_again() {
)
.expect("checkout tree");
- let testfile_path = checkout_dir
- .path()
- .join("test-checkout")
- .join("testdir")
- .join("testfile");
- let testfile_contents = std::fs::read_to_string(testfile_path).expect("test file");
- assert_eq!("test\n", testfile_contents);
+ assert_test_file(checkout_dir.path());
+}
+
+#[test]
+fn should_checkout_at_with_none_options() {
+ let test_repo = TestRepo::new();
+ let checksum = test_repo.test_commit("test");
+ let checkout_dir = tempfile::tempdir().expect("checkout dir");
+
+ let dirfd = openat::Dir::open(checkout_dir.path()).expect("openat");
+ test_repo
+ .repo
+ .checkout_at(
+ None,
+ dirfd.as_raw_fd(),
+ "test-checkout",
+ &checksum,
+ NONE_CANCELLABLE,
+ )
+ .expect("checkout at");
+
+ assert_test_file(checkout_dir.path());
+}
+
+#[test]
+fn should_checkout_at_with_options() {
+ let test_repo = TestRepo::new();
+ let checksum = test_repo.test_commit("test");
+ let checkout_dir = tempfile::tempdir().expect("checkout dir");
+
+ let dirfd = openat::Dir::open(checkout_dir.path()).expect("openat");
+ test_repo
+ .repo
+ .checkout_at(
+ Some(&RepoCheckoutAtOptions {
+ mode: RepoCheckoutMode::User,
+ overwrite_mode: RepoCheckoutOverwriteMode::UnionIdentical,
+ ..Default::default()
+ }),
+ dirfd.as_raw_fd(),
+ "test-checkout",
+ &checksum,
+ NONE_CANCELLABLE,
+ )
+ .expect("checkout at");
+
+ assert_test_file(checkout_dir.path());
}